﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint;

namespace $rootnamespace$.$subnamespace$
{
    public interface I$safeitemrootname$
    {
        #region Observer pattern that allows views to subscribe to events from the model
        List<I$subnamespace$View> Observers { get; }
        void Subscribe(I$subnamespace$View view);
        void UnSubscribe(I$subnamespace$View view);
        #endregion

        void AddToController(I$subnamespace$Controller newController);
    }

    /// <summary>
    /// Models represent knowledge. A model could be a single object (rather uninteresting), or it
    /// could be some structure of objects.
    /// There should be a one-to-one correspondence between the model and its parts on the one
    /// hand, and the represented world as perceived by the owner of the model on the other hand.
    /// The nodes of a model should therefore represent an identifiable part of the problem.
    /// The nodes of a model should all be on the same problem level, it is confusing and considered
    /// bad form to mix problem-oriented nodes (e.g. calendar appointments) with implementation
    /// details (e.g. paragraphs).
    /// </summary>
    public class $safeitemrootname$ : SPQuery, I$safeitemrootname$
    {
        /// <summary>
        /// The controllers that this model are part of
        /// </summary>
        private List<I$subnamespace$Controller> controllers;

        #region Observer pattern that allows views to subscribe to model events

        /// <summary>
        /// Views that are observing this model
        /// </summary>
        private List<I$subnamespace$View> observers;

        public $subnamespace$Model()
        {
            InitModel();
        }

        void InitModel()
        {
            // Start off with no controllers for this model
            controllers = new List<I$subnamespace$Controller>();

            // Start off with no views observing this model
            observers = new List<I$subnamespace$View>();
        }

        /// <summary>
        /// Get the views that are observers for the events. This allows the views to decide for themselves wheater to subscribe or not.
        /// You can create more subscribers with more granularity, ex. one for a click event and one for the keypress event etc. if needed.
        /// </summary>
        List<I$subnamespace$View> I$subnamespace$Model.Observers
        {
            get { return observers; }
        }

        /// <summary>
        /// Allows a view to subscribe to events from its model
        /// </summary>
        /// <param name="view">View that wants to subscribe</param>
        void I$subnamespace$Model.Subscribe(I$subnamespace$View view)
        {
            observers.Add(view);
        }

        /// <summary>
        /// Allows a view to unsubscribe from events from its model
        /// </summary>
        /// <param name="view">View that wants to unsubscribe</param>
        /// <returns>True if success, false if failed</returns>
        void I$subnamespace$Model.UnSubscribe(I$subnamespace$View view)
        {
            observers.Remove(view);
        }

        #endregion

        /// <summary>
        /// Event that is called when a model is added to a controller
        /// </summary>
        /// <param name="newController">Controller that the model was added to</param>
        /// <returns>False if rejected by the model</returns>
        void I$subnamespace$Model.AddToController(I$subnamespace$Controller newController)
        {
            // Store the controller
            controllers.Add(newController);
        }

        /// <summary>
        /// Example of an event method that will have its events fired from the controller
        /// You can make as many events as you wan't
        /// </summary>
        public void GetUserTasks()
        {
            List<string> tasks = new List<string>();

            using (SPWeb rootWeb = SPContext.Current.Site.RootWeb)
            {
                // Get the Tasks list
                SPList taskList = rootWeb.Lists.TryGetList("Tasks");

                if (taskList != null)
                {
                    // Add a CAML query to filter out tasks that are not completed
                    this.Query = "<Where><Eq><FieldRef Name='Status'/><Value Type='Text'>Completed</Value></Eq></Where>";
                    SPListItemCollection collListItems = taskList.GetItems(this);

                    // Copy all task titles to a non-SharePoint type collection
                    tasks.AddRange(from SPListItem oListItem in collListItems select oListItem["Title"].ToString());
                }
            }

            // Only apply for the view in question.
            foreach ($subnamespace$View view in observers.OfType<$subnamespace$View>())
                (view as $subnamespace$View).RefreshTaskList(tasks);
        }
    }
}
